package pl.edu.agh.iosr.gamblingzone.model;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;


import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.hibernate.validator.Length;
import org.hibernate.validator.Email;

@AttributeOverride(name="id",
        column=@Column(name="USER_ID"))
@Entity(name="USERS")
@Name("user")
//@Scope(ScopeType.SESSION)
@Inheritance(strategy = InheritanceType.JOINED)
public class User extends IEntity {

    @Column(name="USER_FIRST_NAME", nullable=false)
    private String firstName;
    
    @Column(name="USER_SURNAME", nullable=false)
    private String surname;

    @Length(min=5, max=15)  
    @Column(name="USER_LOGIN_NAME", nullable=false, unique=true)
    private String loginName;
    
    @Column(name="USER_ROLE", nullable=false)
    private String role;
    
    @Email
    @Column(name="USER_EMAIL", nullable=false)
    private String email;
    
    @Column(name="USER_BIRTHDAY", nullable=false)
    private Date birthDate;

    @Length(min=5, max=15)  
    @Column(name="USER_PASSWORD", nullable=false)
    private String password;
    
    @Column(name="USER_REGISTER_DATE", nullable=false)
    private Date regiserDate = new Date();
    
    @Column(name="USER_LAST_VISIT_DATE", nullable=false)
    private Date lastVisitDate = new Date();
    
    @Column(name="USER_IS_BLOCKED", nullable=false)
    private boolean isBlocked = false;
    
    @Column(name="USER_IS_CANCELLED", nullable=false)
    private boolean isCancelled = false;
    
    @Column(name="USER_BALANCE", nullable=false)
    private Long balance = 0L;
    
// TODO zmieniallem nullable zeby latwiej sie dodawalo!!!!
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="USER_TEMP_BETTING_SLIP_ID", nullable=true)
    private BettingSlip tempBettingSlip;
    
    @OneToMany(mappedBy="owner", cascade=CascadeType.ALL)
    private List<BettingSlip> bettingSlips = new ArrayList<BettingSlip>();
    
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getSurname() {
        return surname;
    }
    public void setSurname(String surname) {
        this.surname = surname;
    }
    public String getLoginName() {
        return loginName;
    }
    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Date getBirthDate() {
        return birthDate;
    }
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
    public String getPassword() {
        return password;
    }
    
    public static String computeSHA1(String in) {
        String out = "";
        
        if(in != null || "".equals(in)) {
            byte [] textPassword = in.getBytes();
            try {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(textPassword);
                byte[] encryptedPassword = md.digest();
                
                for(Byte b : encryptedPassword) {
                    out += Integer.toHexString(b & 0xff );
                }
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        
        return out;
    }
    
    public void setPassword(String password) {
        //this.password = computeSHA1(password);
        this.password = password;
    }
    
    public Date getRegiserDate() {
        return regiserDate;
    }
    public void setRegiserDate(Date regiserDate) {
        this.regiserDate = regiserDate;
    }
    public Date getLastVisitDate() {
        return lastVisitDate;
    }
    public void setLastVisitDate(Date lastVisitDate) {
        this.lastVisitDate = lastVisitDate;
    }
    public boolean isBlocked() {
        return isBlocked;
    }
    public void setBlocked(boolean isBlocked) {
        this.isBlocked = isBlocked;
    }
    public boolean isCancelled() {
        return isCancelled;
    }
    public void setCancelled(boolean isCancelled) {
        this.isCancelled = isCancelled;
    }
    public Long getBalance() {
        return balance;
    }
    public void setBalance(Long balance) {
        this.balance = balance;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public void addBettingSlip(BettingSlip b) {
        bettingSlips.add(b);
        b.setOwner(this);
    }
    public List<BettingSlip> getBettingSlips() {
        return bettingSlips;
    }
    public BettingSlip getTempBettingSlip() {
        return tempBettingSlip;
    }
    public void setTempBettingSlip(BettingSlip tempBettingSlip) {
        this.tempBettingSlip = tempBettingSlip;
    }
    
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;

        final User user = (User) o;

        if (!loginName.equals(user.loginName)) return false;
        if (!password.equals(user.password)) return false;

        return true;
    }
    
    public int hashCode() {
        // TODO
        return loginName.hashCode();
    }
}